<template>
	<view class="collapse">
		<slot />
	</view>
</template>
<script lang="ts">
	import {
		defineComponent
	} from 'vue'
	import mpMixin from '../../libs/mixin/mpMixin'
	/**
	 * collapse 折叠面板 
	 * @description 通过折叠面板收纳内容区域
	 * @tutorial https://www.uviewui.com/components/collapse.html
	 * @property {String | Number | Array}	value		当前展开面板的name，非手风琴模式：[<string | number>]，手风琴模式：string | number
	 * @property {Boolean}					accordion	是否手风琴模式（ 默认 false ）
	 * @property {Boolean}					border		是否显示外边框 ( 默认 true ）
	 * @event {Function}	change 		当前激活面板展开时触发(如果是手风琴模式，参数activeNames类型为String，否则为Array)
	 * @example <e-collapse></e-collapse>
	 */
	export default defineComponent({
		name: "e-collapse",
		mixins: [mpMixin]
	});
</script>
<script setup lang="ts">
	import {
		reactive,
		watch,
		provide,
		toRefs
	} from 'vue'
	import {
		collapseProps,
		collapseEmits,
		type ChangeArr
	} from './props'
	import {
		useDefaultProps
	} from '../../libs/hooks'
	import componentsProps from "../../libs/config/componentsProps";
	import {
		collapseContextKey,
		type CollapseItemContext,
		type CollapseContext
	} from '../../libs/tokens'
	import type {
		 CollapseProps
	} from "../../libs/config/propsType";

	const {
		collapse: collapseDefaultProps
	} = toRefs(componentsProps);

	const _props = defineProps(collapseProps)
	const props = useDefaultProps < CollapseProps > (_props, collapseDefaultProps);
	const emit = defineEmits(collapseEmits)
	const children: Array < CollapseItemContext > = []

	// 暴露给子组件调用的方法，每个子组件都会在初始化时调用
	const addField: CollapseContext['addField'] = item => {
		children.push(item)
	}
	// 删除某个子组件
	const removeField: CollapseContext['removeField'] = (uid) => {
		const index = children.findIndex((item) => item.uid === uid)
		if (index !== -1) {
			children.splice(index, 1)
		}
	}
	const init = () => {
		children.forEach(item => {
			item.init()
		})
	}
	/**
	 * collapse-item被点击时触发，由collapse统一处理各子组件的状态
	 * @param {Object} target 被操作的面板的实例
	 */
	const onChange: CollapseContext['onChange'] = target => {
		let changeArr: ChangeArr = []
		children.forEach((child, index) => {
			// 如果是手风琴模式，将其他的折叠面板收起来
			if (props.value.accordion) {
				child.states.expanded = child.uid === target.uid ? !target.expanded : false
				child.setContentAnimate()
			} else {
				if (child.uid === target.uid) {
					child.states.expanded = !child.states.expanded
					child.setContentAnimate()
				}
			}
			// 拼接change事件中，数组元素的状态
			changeArr.push({
				// 如果没有定义name属性，则默认返回组件的index索引
				name: child.states.name || index,
				status: child.states.expanded ? 'open' : 'close'
			})
		})
		emit('change', changeArr)
		emit(target.expanded ? 'close' : 'open' as any, target.name)
	}
	watch(() => props.value.value,() => {
		init()
	},{
		deep:true
	})
	
	provide(
		collapseContextKey,
		reactive({
			props,
			onChange,
			addField,
			removeField
		})
	)
	defineExpose({
		init
	})
</script>

<style lang="scss" scoped>
	@import "../../libs/theme/collapse.scss";
</style>
